<script setup lang="ts">
import AnswerCardStatus from './components/answer-card-status.vue';
import SubmitConfirmDialog from './components/submit-confirm-dialog.vue';
import type { QuestionItem, QuestionSection } from '#/types/question';
import { useRoute, useRouter } from 'vue-router';
import { useExamSecurity } from '../hooks/useExam';
import { ref, onMounted, onUnmounted, watchEffect, watch } from 'vue';
import { EXAM_SCORE_STATUS } from '../const';
import { useMessageBox } from '#/hooks/useMessageBox';
import { $t } from '@vben/locales';
import { useExamInfo } from '../hooks/useApi';

interface Props {
  sections?: QuestionSection[];
}

const route = useRoute();
const router = useRouter();
const remainingTime = ref('00:00:00');
const showSubmitDialog = ref(false);

withDefaults(defineProps<Props>(), {
  sections: () => []
});

defineOptions({
  name: 'Card',
});
const { confirm: confirmSubmit } = useMessageBox({
  showClose: false,
  showCancelButton: false,
  confirmButtonText: $t('common.submitTxt'),
})
// 定义事件
const emit = defineEmits<{
  questionClick: [question: QuestionItem];
  submit: [submit: boolean, isTerminated: boolean];
  examTerminated: [terminated: boolean];
}>();
// 启动倒计时定时器
let countdownTimer: NodeJS.Timeout | null = null;
let syncTimer: NodeJS.Timeout | null = null;

// 时间基准点（用于精确计算）
const timeBaseline = ref({
  serverStartTime: 0,      // 服务器时间基准点（毫秒时间戳）
  clientStartTime: 0,      // 客户端时间基准点（performance.now()）
  examEndTime: 0,          // 考试结束时间（毫秒时间戳）
  initialized: false,      // 是否已初始化
});

const { examInfo, endTime, refresh } = useExamInfo(route.query.examId as string);

// 处理确认提交
const handleCatchConfirmSubmit = (reason?: string, submit?: boolean, isTerminated?: boolean) => {
  if (reason) {
    confirmSubmit(reason).then(() => {
      router.push({
        path: `/accreditExam/explainCore/${route.query.examId}`
      });
    })
  }
  emit('submit', submit ?? false, isTerminated ?? false);
};

const handleConfirmSubmit = (_reason?: string) => {
  emit('submit', true, true);
};

// 启用考试安全校验
const { /* securityViolation: _securityViolation, */ isExamTerminated } = useExamSecurity(
  handleCatchConfirmSubmit,
  examInfo,
  route.params.id as string
);

/**
 * 初始化时间基准点
 * 建立服务器时间与客户端高精度时间的对应关系
 */
const initializeTimeBaseline = () => {
  if (!examInfo.value?.currentTime || !examInfo.value?.beginTime || !examInfo.value?.duration) {
    return false;
  }

  // 获取服务器当前时间
  const serverCurrentTime = new Date(examInfo.value.currentTime).getTime();

  // 计算考试结束时间
  const examStartTime = new Date(examInfo.value.beginTime).getTime();
  const examDurationMs = examInfo.value.duration * 60 * 1000;
  const examEndTime = examStartTime + examDurationMs;

  // 设置时间基准点
  timeBaseline.value = {
    serverStartTime: serverCurrentTime,
    clientStartTime: performance.now(),
    examEndTime: examEndTime,
    initialized: true
  };
  return true;
};

/**
 * 使用高精度计时器计算当前剩余时间
 * 基于时间基准点，避免累积误差
 */
const calculatePreciseRemainingTime = (): string => {
  if (!timeBaseline.value.initialized) {
    return '00:00:00';
  }
  // 计算从基准点到现在经过的时间（使用高精度计时器）
  const clientElapsed = performance.now() - timeBaseline.value.clientStartTime;
  // 计算当前的服务器时间（基准时间 + 经过时间）
  const currentServerTime = timeBaseline.value.serverStartTime + clientElapsed;
  // 计算剩余时间
  const remainingMs = timeBaseline.value.examEndTime - currentServerTime;
  if (remainingMs <= 0) {
    return '00:00:00';
  }

  // 转换为时分秒格式
  const totalSeconds = Math.floor(remainingMs / 1000);
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const seconds = totalSeconds % 60;

  return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
};

// 计算剩余时间（兼容原有逻辑）
const calculateRemainingTime = () => {
  if (timeBaseline.value.initialized) {
    // 使用精确计算
    remainingTime.value = calculatePreciseRemainingTime();
  } else {
    // 降级到原有逻辑
    if (!examInfo.value?.duration || !examInfo.value?.currentTime || !endTime.value) {
      remainingTime.value = '00:00:00';
      return;
    }

    const currentTime = new Date(examInfo.value?.currentTime).getTime();
    const endTimeDate = new Date(endTime.value).getTime();
    const timeDiff = endTimeDate - currentTime;
    if (timeDiff <= 0) {
      remainingTime.value = '00:00:00';
      return;
    }

    const totalSeconds = Math.floor(timeDiff / 1000);
    const hours = Math.floor(totalSeconds / 3600);
    const minutes = Math.floor((totalSeconds % 3600) / 60);
    const seconds = totalSeconds % 60;
    remainingTime.value = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
  }
};

const startCountdownTimer = () => {
  if (countdownTimer) {
    clearInterval(countdownTimer);
  }
  if (syncTimer) {
    clearInterval(syncTimer);
  }

  // 尝试初始化时间基准点
  const baselineInitialized = initializeTimeBaseline();

  // 立即计算一次剩余时间
  calculateRemainingTime();

  // 启动倒计时定时器
  countdownTimer = setInterval(() => {
    // 如果考试被终止，停止倒计时
    if (isExamTerminated.value) {
      stopCountdownTimer();
      return;
    }

    if (timeBaseline.value.initialized) {
      // 使用精确的高精度计算
      remainingTime.value = calculatePreciseRemainingTime();
    } else {
      // 降级：不再自增 examInfo.currentTime，直接使用已有值计算
      // 重新计算剩余时间
      calculateRemainingTime();
    }

    // 如果剩余时间为0，停止定时器
    if (remainingTime.value === '00:00:00') {
      stopCountdownTimer();
    }
  }, 1000);

  // 如果使用精确计算，启动定期重新校准（每1分钟）
  if (baselineInitialized) {
    syncTimer = setInterval(async () => {
      if (!isExamTerminated.value) {
        await refresh();
        initializeTimeBaseline();
        calculateRemainingTime();
      }
    }, 1 * 60 * 1000);
  }
};

// 停止倒计时定时器
const stopCountdownTimer = () => {
  if (countdownTimer) {
    clearInterval(countdownTimer);
    countdownTimer = null;
  }
  if (syncTimer) {
    clearInterval(syncTimer);
    syncTimer = null;
  }
};

// 监听系统时间变化，启动倒计时
watchEffect(() => {
  if (examInfo.value?.currentTime && examInfo.value?.duration) {
    startCountdownTimer();
  }
});

watch(() => examInfo.value?.examScoreStatus, (status) => {
  if (status && ![EXAM_SCORE_STATUS.ABSENT, EXAM_SCORE_STATUS.EXAMINING].includes(status)) {
    isExamTerminated.value = true
    confirmSubmit($t('examCore.examEndTxt')).then(() => {
      router.push({
        path: `/accreditExam/explainCore/${route.query.examId}`
      });
    }).catch(() => { })
  }
});

watch(() => remainingTime.value, (time, oldTime) => {
  // 只有在真正的倒计时结束时才提交，避免初始化时误触发
  if (time === '00:00:00' && oldTime && oldTime !== '00:00:00' && !isExamTerminated.value) {
    isExamTerminated.value = true;
    handleCatchConfirmSubmit($t('examCore.examEndTxt'), true, false);
  }
});

// 页面可见时强制对时；卸载清理
let onVisChange: (() => void) | null = null;
onMounted(() => {
  onVisChange = async () => {
    if (!document.hidden && !isExamTerminated.value) {
      await refresh();
      initializeTimeBaseline();
      calculateRemainingTime();
    }
  };
  document.addEventListener('visibilitychange', onVisChange);
});

// 组件卸载时清理定时器
onUnmounted(() => {
  if (onVisChange) document.removeEventListener('visibilitychange', onVisChange);
  stopCountdownTimer();
});

// 处理题目点击
const handleQuestionClick = (question: QuestionItem) => {
  emit('questionClick', question);
};

// 处理提交试卷按钮点击
const handleSubmitClick = () => {
  if (isExamTerminated.value) {
    return;
  }
  showSubmitDialog.value = true;
};

// 处理取消提交
const handleCancelSubmit = () => {
  showSubmitDialog.value = false;
};
</script>

<template>
  <div class="answer-card h-full flex flex-col">
    <!-- 考试剩余时间 -->
    <div class="time-section flex-shrink-0">
      <div class="font-medium h-12 flex w-full items-center justify-center">
        <p class="text-[#191919] pr-2 text-[14px]">{{ $t('examCore.examRemainingTime') }}</p>
        <p class="text-[#E5484D] text-2xl text-[14px]">{{ remainingTime }}</p>
      </div>
      <hr class="border-t border-gray-200" />
    </div>
    <!-- 答题卡标题和状态类型 -->
    <div class="card-header flex items-center">
      <span class="card-title">{{ $t('examCore.answerCard') }}</span>
      <AnswerCardStatus :show-legend="true" :show-questions="false" />
    </div>

    <!-- 题目列表 -->
    <div class="flex-1 overflow-y-auto scroll-container">
      <AnswerCardStatus :sections="sections" :show-legend="false" :show-questions="true"
        @question-click="handleQuestionClick" />
    </div>

    <!-- 提交试卷按钮 -->
    <div class="mt-6">
      <el-button class="w-full" type="primary" :disabled="isExamTerminated" @click="handleSubmitClick">
        {{ $t('examCore.submitConfirm') }}
      </el-button>
    </div>

    <!-- 提交确认对话框 -->
    <SubmitConfirmDialog v-model="showSubmitDialog" :sections="sections" @confirm="handleConfirmSubmit"
      @cancel="handleCancelSubmit" />
  </div>
</template>

<style scoped>
.answer-card {
  @apply bg-[#f2f7fd] rounded-lg px-4 pb-4;
}

.time-section {
  @apply mb-4;
}

.card-header {
  @apply flex items-center justify-between mt-1 mb-3;
}

.card-title {
  @apply text-[14px] font-medium text-gray-800;
}

/* 自定义滚动条样式 */
.scroll-container {
  /* 为滚动条留出空间 */
  padding-right: 8px;
}

.scroll-container::-webkit-scrollbar {
  width: 6px;
}

.scroll-container::-webkit-scrollbar-track {
  background: transparent;
  margin-right: 8px;
}

.scroll-container::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.scroll-container::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* Firefox 滚动条样式 */
.scroll-container {
  scrollbar-width: thin;
  scrollbar-color: #c1c1c1 transparent;
}
</style>
